package main

import (
	"database/sql"
	"fmt"
	"github.com/google/uuid"
	"golang.org/x/crypto/bcrypt"
	"io"
	"log"
	"mime/multipart"
	"os"
	"path/filepath"
	"real-time-communication/utils"
	"time"
	"unicode/utf8"
)

type User struct {
	UserId    int    `json:"userId" db:"user_id"`
	Username  string `json:"username" db:"username"`
	Password  string `json:"password" db:"password"`
	Email     string `json:"email" db:"email"`
	Nickname  string `json:"nickname" db:"nickname"`
	Avatar    string `json:"avatar" db:"avatar"`
	LoginIp   string `json:"loginIp" db:"login_Ip"`
	LoginTime string `json:"loginTime" db:"login_time"`
}

type FriendView struct {
	UserId   int    `json:"userId" db:"user_id"`
	Nickname string `json:"nickname" db:"nickname"`
	Avatar   string `json:"avatar" db:"avatar"`
}

type ModifyPassword struct {
	UserId int    `json:"userId" db:"user_id"`
	OldPwd string `json:"oldPwd" db:"password"`
	NewPwd string `json:"newPwd" db:"password"`
}

type ForgetPassword struct {
	Username string `json:"username" db:"username"`
	Password string `json:"password" db:"password"`
}

// QueryUserAvatarAndNickname 通过用户ID获取用户头像和昵称
func QueryUserAvatarAndNickname(userId int) *FriendView {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return nil
	}
	defer db.Close()

	var res FriendView

	stmt, err := db.Prepare("SELECT user_id, nickname, avatar FROM user WHERE user_id = ?")
	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}
	defer stmt.Close()

	err = stmt.QueryRow(userId).Scan(&res.UserId, &res.Nickname, &res.Avatar)

	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}

	return &res
}

func QueryUserNicknameById(userId int) *User {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return nil
	}
	defer db.Close()

	var res User

	stmt, err := db.Prepare("SELECT user_id, nickname FROM user WHERE user_id = ?")
	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}
	defer stmt.Close()

	err = stmt.QueryRow(userId).Scan(&res.UserId, &res.Nickname)

	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}

	return &res
}

func QueryUserProfileByUserId(userId int) *User {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return nil
	}
	defer db.Close()

	var res User

	stmt, err := db.Prepare("SELECT user_id, nickname, avatar FROM user WHERE user_id = ?")
	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}
	defer stmt.Close()

	err = stmt.QueryRow(userId).Scan(&res.UserId, &res.Nickname, &res.Avatar)

	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}

	return &res
}

// QueryUserPasswordHash 获取加密的密码
func QueryUserPasswordHash(userId int) string {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return ""
	}
	defer db.Close()

	var password string

	stmt, err := db.Prepare("SELECT password FROM user WHERE user_id = ?")
	if err != nil {
		log.Fatal("数据库异常", err)
		return ""
	}
	defer stmt.Close()

	err = stmt.QueryRow(userId).Scan(&password)

	if err != nil {
		log.Fatal("数据库异常", err)
		return ""
	}

	return password
}

// ModifyUserPassword 修改用户密码
func ModifyUserPassword(form ModifyPassword) bool {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return false
	}
	defer db.Close()

	hashPassword, err := bcrypt.GenerateFromPassword([]byte(form.NewPwd), bcrypt.DefaultCost)
	if err != nil {
		log.Fatal("创建哈希密码失败", err)
		return false
	}

	stmt, err := db.Prepare("UPDATE user SET password = ? WHERE user_id = ?")
	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}
	defer stmt.Close()

	_, err = stmt.Exec(hashPassword, form.UserId)

	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}

	return true
}

// UploadAvatar 头像上传
func UploadAvatar(file multipart.File, header *multipart.FileHeader) utils.ResultResp {
	ext := filepath.Ext(header.Filename)
	if ext != ".png" && ext != ".jpg" && ext != ".jpeg" {
		return utils.ErrorWithMsg("格式不支持，请上传格式为：PNG, JPG或JPEG的图片")
	}

	timestamp := time.Now().Unix()
	tmp := uuid.New().String()
	fileName := fmt.Sprintf("%d_%s%s", timestamp, tmp, ext)

	filePath := filepath.Join(BASE_URL+"/", fileName)
	out, err := os.Create(filePath)
	if err != nil {
		fmt.Println("无法创建文件:", err)
		return utils.ErrorWithMsg("服务端异常")
	}
	defer out.Close()

	_, err = io.Copy(out, file)
	if err != nil {
		fmt.Println("存储文件异常:", err)
		return utils.ErrorWithMsg("服务端异常")
	}

	return utils.SuccessWithData(SERVER_IP + "/avatar/" + fileName)
}

// ModifyUser 修改用户
func ModifyUser(user User) utils.ResultResp {

	userId := user.UserId
	nickname := user.Nickname
	avatar := user.Avatar

	if utils.IsEmpty(nickname) {
		return utils.ErrorWithMsg("昵称不能为空")
	}

	if utf8.RuneCountInString(nickname) < 2 || utf8.RuneCountInString(nickname) > 6 {
		return utils.ErrorWithMsg("昵称格式不符")
	}

	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Println("数据库异常", err)
		return utils.ErrorWithMsg("服务端异常")
	}
	defer db.Close()

	stmt, err := db.Prepare("UPDATE user SET nickname = ?, avatar = ? WHERE user_id = ?")
	if err != nil {
		log.Println("数据库异常", err)
		return utils.ErrorWithMsg("服务端异常")
	}
	defer stmt.Close()

	_, err = stmt.Exec(nickname, avatar, userId)
	if err != nil {
		log.Println("数据库异常", err)
		return utils.ErrorWithMsg("服务端异常")
	}

	return utils.SuccessWithMsg("修改成功")
}
